<?php
/**
 * singleton class
 *
 * using example:
 * class mysingleton extends singleton {
 *	// php singleton wrapper
 *	static public function &instance( ) { return parent::instance( __CLASS__ ); }
 * 	// your methods ...
 * }
 *
 * // next everywhere in code just
 * // use instance static method of your class
 * // to get unique instance of your class
 * mysingleton::instancee( ); // returns instance;
 *
 * @version:	0.1
 * @package:	radcore
 * @created:	11 nov 2008
 * @link:		http://radiance-project.com/
 * @link:		http://qfox.ru/
 * @author:		alex <alex@qfox.ru> yaroshevich
 * @copyright:	(c) 2008-2011 radiance framework
 */

class singleton
{
	/**
	 * abstract constructor
	 */
	private function __construct( ) { throw new Exception( "You must describe private constructor." ); }
	
	private static $instances = array( );
	
	/**
	 * singleton generator
	 *
	 * @access public
	 * @static
	 * @param	String	__CLASS__
	 * @return	unique instance of class
	 */
	static public function &instance( )
	{
		$c = func_num_args() ? func_get_arg(0) : null;
		
		if( is_null( $c ) ) { throw new Exception( "You must specify static public method instance(){ return parent::instance(__CLASS__); } method in your class." ); }
		
		if( !is_array( self::$instances ) )
			self::$instances = array( );
		
		if( !array_key_exists($c, self::$instances) )
			self::$instances[$c] = new $c( );
		
		return self::$instances[$c];
	}
	
	static public function classes( )
	{
		return array_keys( self::$instances );
	}
	
	static public function search( $c = null )
	{
		return ( !is_null($c) && array_key_exists($c,self::$instances) )
			? self::$instances[$c]
			: self::$instances;
	}
	
	static public function destroy( $c )
	{
		if( !array_key_exists($c, self::$instances) )
			return null;
		
		self::$instances[$c] ->__destruct( );
		self::delete( $c );
		
		return true;
	}
	
	static public function delete( $c )
	{
		unset( self::$instances[$c] );
	}
	
	public function __clone() { throw new Exception( "Clone is not allowed." ); }
	
}
 
?>